package com.boss.salary.controller;

import com.alibaba.excel.support.ExcelTypeEnum;
import com.boss.api.dto.ApiResultDTO;
import com.boss.asset.service.IAssetInfoService;
import com.boss.common.base.BasicinfoBaseController;
import com.boss.common.service.ICommonService;
import com.boss.framework.exception.AppRuntimeException;
import com.boss.salary.ExcelModel.ExcelResult;
import com.boss.salary.ExcelModel.PersonBankModel;
import com.boss.salary.ExcelModel.QuerySalaryDataModel;
import com.boss.salary.ExcelModel.SalaryRentalModel;
import com.boss.salary.constant.ApiElementConstant;
import com.boss.salary.entity.*;
import com.boss.salary.parsingExcel.ExcelParsingService;
import com.boss.salary.parsingExcel.impl.ReadSalaryReportExcel;
import com.boss.salary.parsingExcel.impl.WriteSalaryReportExcel;
import com.boss.salary.service.*;
import com.boss.salary.utils.ExcelUtils;
import com.boss.salary.vo.AgencySalaryVO;
import com.boss.sys.ca.user.dto.UserDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class ExcelController  extends BasicinfoBaseController {

    /**
     * 引入日志框架常量
     */
    private final static Logger logger = LoggerFactory.getLogger(ExcelController.class);

    @Resource(name = "personBankExcelParsingServiceImpl")
    private ExcelParsingService excelParsingService;


    @Autowired
    private IPersonOperateService iPersonOperateService;


    @Autowired
    private IPersonInfoService iPersonInfoService;

    @Autowired
    private ISalaryHistoryService iSalaryHistoryService;

    @Autowired
    private ICommonService iCommonService;

    @Autowired
    private IQuerySalaryDataService iQuerySalaryDataService;

    @Autowired
    private IAssetInfoService assetInfoService;

    @Autowired
    private IAgencySalaryService service;

    @Autowired
    private IDepartmentInfoService iDepartmentInfoService;

    @Autowired
    private IAgencyInfoService iAgencyInfoService;

    @Autowired
    private WriteSalaryReportExcel writeSalaryReportExcel;

    @Autowired
    private ReadSalaryReportExcel readSalaryReportExcel;

    @Autowired
    private IOperrateLogsService iOperrateLogsService;


    @PostMapping("/boss_Salary_vue/excel/upload")
    public ApiResultDTO uploadExcel(@RequestHeader("X-Token") String tokenid,
                                    @RequestParam("file")MultipartFile file,
                                    @RequestParam("agencyId") String agencyId) {
        InputStream inputStream=null;
        try {
            UserDTO userDto = getUser(tokenid);
             inputStream = new BufferedInputStream(file.getInputStream());
            ExcelResult<PersonOperate> personAll = excelParsingService.readExcelWithModel(inputStream, PersonBankModel.class, ExcelTypeEnum.valueOf(inputStream),userDto);
            List<PersonOperate> successList = personAll.getSuccessList();
            List<List<String>> errorList = personAll.getErrorList();
            if (errorList.size() > 0) {
                return ApiResultDTO.error(ERROR_RSCODE, errorList.toString());
            } else {
                iPersonOperateService.importExcelBankData(successList,userDto,agencyId);
                return ApiResultDTO.success();
            }
        } catch (IOException e) {
            logger.error("上传失败！", e.getMessage());
            return ApiResultDTO.error(ERROR_RSCODE,"上传失败！");
        } catch (Exception e) {
            logger.error("上传失败！", e.getMessage());
            return ApiResultDTO.error(ERROR_RSCODE,e.getMessage());
        }finally {
            if(inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @RequestMapping( value = "/boss_Salary_vue/excel/downloadModel", method = RequestMethod.GET )
    public ApiResultDTO downloadExcel(HttpServletResponse res ){
        String fileName = "人员信息模板";
        OutputStream outputStream=null;
        outputStream=getOutputStream(fileName,res);
        List<PersonBankModel> modelList=new ArrayList<>();
        modelList.add(new PersonBankModel());
        ExcelUtils.writeExcelWithModel(outputStream,modelList,PersonBankModel.class,null);
        return ApiResultDTO.success();
    }

    /**
     * 导出文件时为Writer生成OutputStream
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws AppRuntimeException{
        //创建本地文件
//        fileName = fileName ;

        try {

            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            fileName = URLEncoder.encode(fileName,"UTF-8");
            fileName=new String(fileName.getBytes(), "iso-8859-1");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName+ ".xls");

            return response.getOutputStream();
        } catch (Exception e) {

            throw new AppRuntimeException("下载失败");
        }
    }

    /**
     * 导出人员变动编辑
     * @return
     */
    @GetMapping("/outPutPersonOperateList")
    public ApiResultDTO outPutPersonOperateList( @RequestHeader("X-Token") String tokenid,
                                                 @RequestParam(value = "agencyId") String agencyId,
                                                 HttpServletResponse response){

        try {
            UserDTO userDTO = getUser(tokenid);

            List<PersonInfo> allAgencyInfo = iPersonInfoService.getAllPersonInfo(agencyId);
            List<Map<String, String>> bank = assetInfoService.getBaseDataSelect(ApiElementConstant.SALBANK, userDTO.getProvince());

            List<PersonBankModel> personBankModels = new ArrayList<>();
            if (allAgencyInfo.size() > 0) {
                for (PersonInfo personInfo : allAgencyInfo) {
                    PersonBankModel personBankModel = new PersonBankModel();
                    personBankModel.setPersonName(personInfo.getPersonName());
                    personBankModel.setIdenNo(personInfo.getIdenNo());
                    if (!StringUtils.isEmpty(personInfo.getSalaCardBank())) {
                        for (Map<String, String> bankCode : bank) {
                            if (personInfo.getSalaCardBank().equals(bankCode.get("code"))) {
                                personBankModel.setSalaCardBank(bankCode.get("name"));
                            }
                        }
                    }
                    personBankModel.setSalaCardNo(personInfo.getSalaCardNo());
                    personBankModels.add(personBankModel);
                }
            }


            String fileName = "人员变动编辑";
            OutputStream outputStream = null;
            outputStream = getOutputStream(fileName, response);
            ExcelUtils.writeExcelWithModel(outputStream, personBankModels, PersonBankModel.class, ExcelTypeEnum.XLS);
            return ApiResultDTO.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResultDTO.error(e.getMessage());
        }
    }

    /**
     * 月结导出
     * @return
     */
    @GetMapping("/outPutSalaryMonthEndList")
    public ApiResultDTO outPutSalaryMonthEndList(@RequestHeader("X-Token") String tokenid,
                                                 @RequestParam(value = "agencyId") String agencyId,
                                                 @RequestParam(value = "flag") String flag,
                                                 HttpServletResponse response){
        try {
            UserDTO userDTO = getUser(tokenid);
            List<String> childrenIds = iCommonService.getAgencyChildrenId(userDTO, agencyId,tokenid);
            Map<String, Object> queryParam =new HashMap<>();
            List<SalaryRentalModel>SalaryRentalModels=new ArrayList<>();
            List<SalaryRental> salaryList=null;
            if("0".equals(flag)){
                salaryList=iSalaryHistoryService.getSalaryMonth(queryParam,childrenIds);
            }else if("1".equals(flag)){
                salaryList=iSalaryHistoryService.getSalaryMonthHistory(queryParam,childrenIds);
            }

            if(salaryList.size()>0){
                for (SalaryRental salaryRental : salaryList) {
                    SalaryRentalModel salaryRentalModel=new SalaryRentalModel();
                    if("0".equals(salaryRental.getIsMonthEnd())){
                        salaryRentalModel.setIsMonthEnd("未月结");
                    }else if("1".equals(salaryRental.getIsMonthEnd())){
                        salaryRentalModel.setIsMonthEnd("已月结");
                    }
                    salaryRentalModel.setAgencyCode(salaryRental.getAgencyCode());
                    salaryRentalModel.setAgencyName(salaryRental.getAgencyName());
                    salaryRentalModel.setMonth(salaryRental.getMonth());
                    salaryRentalModel.setYfgzze(salaryRental.getYfgzze());
                    salaryRentalModel.setSfgzze(salaryRental.getSfgzze());
                    SalaryRentalModels.add(salaryRentalModel);
                }
            }
            String fileName = "月结数据";
            OutputStream outputStream=null;
            outputStream=getOutputStream(fileName,response);
            ExcelUtils.writeExcelWithModel(outputStream,SalaryRentalModels,SalaryRentalModel.class,ExcelTypeEnum.XLS);
            return ApiResultDTO.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "导出失败");
        }
    }

    /**
     * 查询工资数据导出
     * @return
     */
    @GetMapping("/outPutPayrollDataList")
    public ApiResultDTO outPutPayrollDataList(@RequestHeader("X-Token") String tokenid,
                                              @RequestParam(value = "choiceOfTime") String choiceOfTime,
                                              @RequestParam(value = "agencyId") String agencyId,
                                              HttpServletResponse response){
        try {
            UserDTO userDTO = getUser(tokenid);
            List<String> childrenIds = iCommonService.getAgencyChildrenId(userDTO, agencyId,tokenid);
            Map<String, Object> queryParam =new HashMap<>();
            queryParam.put("choiceOfTime",choiceOfTime);
            List<QuerySalaryData> QuerySalaryDatas = iQuerySalaryDataService.getPayrollData(queryParam,childrenIds);
            List<QuerySalaryDataModel>QuerySalaryDataModels=new ArrayList<>();

            if(QuerySalaryDatas.size()>0){
                for (QuerySalaryData querySalaryData : QuerySalaryDatas) {
                    QuerySalaryDataModel querySalaryDataModel=new QuerySalaryDataModel();
                    querySalaryDataModel.setAgencyName(querySalaryData.getAgencyName());
                    querySalaryDataModel.setRegisterSalary(querySalaryData.getRegisterSalary());
                    querySalaryDataModel.setQuitSalary(querySalaryData.getQuitSalary());
                    querySalaryDataModel.setTotalSalary(querySalaryData.getTotalSalary());
                    QuerySalaryDataModels.add(querySalaryDataModel);
                }
            }
            String fileName = "工资支付数据";
            OutputStream outputStream=null;
            outputStream=getOutputStream(fileName,response);
            ExcelUtils.writeExcelWithModel(outputStream,QuerySalaryDataModels,QuerySalaryDataModel.class,ExcelTypeEnum.XLS);
            return ApiResultDTO.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "导出失败");
        }
    }


   /**
     * 单位工资编报导入
     * @return
     */
    @PostMapping("/ImportSalaryReportList")
    public ApiResultDTO ImportSalaryReportList(@RequestHeader("X-Token") String tokenid,
                                               @RequestParam("file") MultipartFile file,
                                               @RequestParam(value = "agencyId") String agencyId){
        try {
            UserDTO userDTO = getUser(tokenid);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDTO.getProvince());
            operrateLogs.setTokenId(tokenid);
            operrateLogs.setUserAgencyId(userDTO.getAgency());
            operrateLogs.setUeserName(userDTO.getName());
            operrateLogs.setOperateName("单位工资编报--单位工资编报--导入");
            operrateLogs.setAgencyId(agencyId);
            iOperrateLogsService.saveOperrateLogs(operrateLogs);
            List<AgencySalaryVO> exccelColumnName = service.getExccelColumnName(userDTO);
            String province = userDTO.getProvince();
            readSalaryReportExcel.Read(file, province, agencyId, exccelColumnName);
            return ApiResultDTO.success();
        } catch (AppRuntimeException e){
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "导入失败"+e.getMessage());
        }

    }

    /**
     * 单位工资编报导入
     * @return
     */
    @PostMapping("/ImportSalaryReportListAsync")
    public ApiResultDTO ImportSalaryReportListAsync(@RequestHeader("X-Token") String tokenid,
                                               @RequestParam("file") MultipartFile file,
                                               @RequestParam(value = "agencyId") String agencyId){
        try {
            UserDTO userDTO = getUser(tokenid);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDTO.getProvince());
            operrateLogs.setTokenId(tokenid);
            operrateLogs.setUserAgencyId(userDTO.getAgency());
            operrateLogs.setUeserName(userDTO.getName());
            operrateLogs.setOperateName("单位工资编报--单位工资编报--导入");
            operrateLogs.setAgencyId(agencyId);
            iOperrateLogsService.saveOperrateLogs(operrateLogs);
            List<AgencySalaryVO> exccelColumnName = service.getExccelColumnName(userDTO);
            String province = userDTO.getProvince();
            Map<String,String> remap=readSalaryReportExcel.ReadAsync(file, province, agencyId, exccelColumnName);
            return ApiResultDTO.success(remap);
        } catch (AppRuntimeException e){
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "导入失败"+e.getMessage());
        }

    }

    /**
     * 单位工资编报导出
     * @return
     */
    @GetMapping("/outPutSalaryReportList")
    public ApiResultDTO outPutSalaryReportList( @RequestHeader("X-Token") String tokenid,
                                                @RequestParam(value = "agencyId") String agencyId,
                                                @RequestParam(value = "flag") String flag,
                                                @RequestParam(value = "datatype",required = false) String datatype,
                                                @RequestParam Map<String,Object> condition,
                                                HttpServletResponse response){
        try {
            UserDTO userDTO = getUser(tokenid);
            List<Map<String, Object>> unitSalaryReport = service.getUnitSalaryReport(userDTO,agencyId, datatype, condition);
            List<AgencySalaryVO> exccelColumnName = service.getExccelColumnName(userDTO);
            String fileName = "单位工资编报";
            OutputStream outputStream = getOutputStream(fileName,response);
            writeSalaryReportExcel.writeExcel03(unitSalaryReport,exccelColumnName,outputStream);
            return ApiResultDTO.success();
        } catch (Exception e){
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "导出失败");
        }
    }



    /**
     * 导入全部工资
     * @return
     */
    @PostMapping("/allImportSalaryReportList")
    public ApiResultDTO allImportSalaryReportList(@RequestHeader("X-Token") String tokenid,
                                               @RequestParam("file") MultipartFile file
                                               ){
        try {
            UserDTO userDTO = getUser(tokenid);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDTO.getProvince());
            operrateLogs.setTokenId(tokenid);
            operrateLogs.setUserAgencyId(userDTO.getAgency());
            operrateLogs.setUeserName(userDTO.getName());
            operrateLogs.setOperateName("单位工资编报--单位工资编报--导入");
            //operrateLogs.setAgencyId(agencyId);
            iOperrateLogsService.saveOperrateLogs(operrateLogs);
            List<AgencySalaryVO> exccelColumnName = service.getExccelColumnName(userDTO);
            String province = userDTO.getProvince();
            readSalaryReportExcel.Reads(file, province, exccelColumnName);
            return ApiResultDTO.success();
        } catch (AppRuntimeException e){
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "导入失败"+e.getMessage());
        }

    }
}
